home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / ldb / mach-os.c < prev    next >
C/C++ Source or Header  |  1992-05-19  |  4KB  |  181 lines

  1. /*
  2.  * $Header: mach-os.c,v 1.5 92/04/08 03:25:15 wlott Exp $
  3.  *
  4.  * OS-dependent routines.  This file (along with os.h) exports an
  5.  * OS-independent interface to the operating system VM facilities.
  6.  * Suprisingly, this interface looks a lot like the Mach interface
  7.  * (but simpler in some places).  For some operating systems, a subset
  8.  * of these functions will have to be emulated.
  9.  *
  10.  * This is the Mach version.
  11.  *
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <mach.h>
  16. #include "./signal.h"
  17. #include "ldb.h"
  18. #include "os.h"
  19.  
  20. #define MAX_SEGS 32
  21.  
  22. static struct segment {
  23.     vm_address_t start;
  24.     vm_size_t length;
  25. } addr_map[MAX_SEGS];
  26. static int segments = -1;
  27.  
  28. vm_size_t os_vm_page_size;
  29.  
  30. void os_init()
  31. {
  32.     os_vm_page_size = vm_page_size;
  33. }
  34.  
  35. os_vm_address_t os_validate(addr, len)
  36. vm_address_t addr;
  37. vm_size_t len;
  38. {
  39.     kern_return_t res;
  40.  
  41. #if defined(EXT_PAGER)
  42.     res = pager_vm_allocate(task_self(), &addr, len, addr==NULL);
  43. #else
  44.     res = vm_allocate(task_self(), &addr, len, addr==NULL);
  45. #endif
  46.  
  47.     if (res != KERN_SUCCESS)
  48.     return 0;
  49.  
  50.     segments = -1;
  51.  
  52.     vm_protect(task_self(), addr, len, TRUE,
  53.            VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  54.  
  55.     return addr;
  56. }
  57.  
  58. void os_invalidate(addr, len)
  59. vm_address_t addr;
  60. vm_size_t len;
  61. {
  62.     kern_return_t res;
  63.  
  64. #if defined(EXT_PAGER)
  65.     res = pager_vm_deallocate(task_self(), addr, len);
  66. #else
  67.     res = vm_deallocate(task_self(), addr, len);
  68. #endif
  69.  
  70.     if (res != KERN_SUCCESS)
  71.         mach_error("Could not vm_allocate memory: ", res);
  72.  
  73.     segments = -1;
  74. }
  75.  
  76. vm_address_t os_map(fd, offset, addr, len)
  77. int fd, offset;
  78. vm_address_t addr;
  79. vm_size_t len;
  80. {
  81.     kern_return_t res;
  82.  
  83. #if defined(EXT_PAGER)
  84.     res = pager_map_fd(fd, offset, &addr, 0, len);
  85. #else
  86.     res = map_fd(fd, offset, &addr, 0, len);
  87. #endif
  88.  
  89.     if (res != KERN_SUCCESS)
  90.         mach_error("Could not map_fd memory: ", res);
  91.  
  92.     segments = -1;
  93.  
  94.     vm_protect(task_self(), addr, len, TRUE,
  95.            VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
  96.  
  97.     return addr;
  98. }
  99.  
  100. void os_flush_icache(address, length)
  101. vm_address_t address;
  102. vm_size_t length;
  103. {
  104. #ifdef mips
  105.     vm_machine_attribute_val_t flush;
  106.     kern_return_t kr;
  107.  
  108.     flush = MATTR_VAL_ICACHE_FLUSH;
  109.  
  110.     kr = vm_machine_attribute(task_self(), address, length,
  111.                   MATTR_CACHE, &flush);
  112.     if (kr != KERN_SUCCESS)
  113.         mach_error("Could not flush the instruction cache", kr);
  114. #endif
  115. }
  116.  
  117. void os_protect(address, length, protection)
  118. vm_address_t address;
  119. vm_size_t length;
  120. vm_prot_t protection;
  121. {
  122.     vm_protect(task_self(), address, length, FALSE, protection);
  123. }
  124.  
  125.  
  126. boolean valid_addr(test)
  127. vm_address_t test;
  128. {
  129.     vm_address_t addr;
  130.     vm_size_t size;
  131.     long bullshit;
  132.     int curseg;
  133.  
  134.     if (segments == -1) {
  135.         addr = 0;
  136.         curseg = 0;
  137.  
  138.         while (1) {
  139.             if (vm_region(task_self(), &addr, &size, &bullshit, &bullshit, &bullshit, &bullshit, &bullshit, &bullshit) != KERN_SUCCESS)
  140.                 break;
  141.  
  142.             if (curseg > 0 && addr_map[curseg-1].start + addr_map[curseg-1].length == addr)
  143.                 addr_map[curseg-1].length += size;
  144.             else {
  145.                 addr_map[curseg].start = addr;
  146.                 addr_map[curseg].length = size;
  147.                 curseg++;
  148.             }
  149.  
  150.             addr += size;
  151.         }
  152.  
  153.         segments = curseg;
  154.     }
  155.     
  156.     for (curseg = 0; curseg < segments; curseg++)
  157.         if (addr_map[curseg].start <= test && test < addr_map[curseg].start + addr_map[curseg].length)
  158.             return TRUE;
  159.     return FALSE;
  160. }
  161.  
  162. #ifndef ibmrt
  163. static void sigbus_handler(signal, code, context)
  164. int signal, code;
  165. struct sigcontext *context;
  166. {
  167.     if(!interrupt_maybe_gc(context))
  168.     interrupt_handle_now(signal, code, context);
  169. }
  170. #endif
  171.  
  172. void os_install_interrupt_handlers()
  173. {
  174. #ifndef ibmrt
  175.     interrupt_install_low_level_handler(SIGBUS,sigbus_handler);
  176. #endif
  177. #ifdef mips
  178.     interrupt_install_low_level_handler(SIGSEGV,sigbus_handler);
  179. #endif
  180. }
  181.